using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using RFS.BizLogic.PaiShi.Ports;
using RFS.BizLogic.PaiShi.Ports.Adapters;
using RFS.Domain.PaiShi;
using RFS.Domain.PaiShi.Accounting;
using RFS.Domain.PaiShi.WorkFlow;
using RFS.Domain.Sys;

namespace RFS.BizLogic.PaiShi.Accounting
{
    public class AccountingVoucherManager : IAccountingVoucherManager
    {
        // public IOrderItemBasedAccountingVoucher CreateAV(IOrderItem gho, IOrderItem yso=default)
        // {
        //     //1 create a av object and put it into 
        //
        //     var av = new OrderItemBasedAccountingVoucher();
        //
        //     if (gho != default)
        //     {
        //         av.AddAccItem(gho, Account.KCSP, $"供货_{gho.Product.Key}_{gho.BizId}" ,  amountDebit :  GetAmount(gho)  ); //j
        //
        //     }
        //
        //     if (yso != null)
        //     {
        //         av.AddAccItem(yso, Account.KCSP, $"验收_{yso.Product.Key}_{yso.BizId}" , amountCredit  :  GetAmount(yso)  ); //d
        //
        //     }
        //     
        //     
        //
        //     return av;
        // }

        // public IOrderItemBasedAccountingVoucher CreateAV( IEnumerable<IOrderItem> ghos,  IEnumerable<IOrderItem> ysos)
        // {
        //     //1 create a av object and put it into 
        //
        //     var av = new OrderItemBasedAccountingVoucher();
        //     
        //     foreach (var gho in ghos)
        //     {
        //         av.AddAccItem(gho, Account.KCSP, $"供货_{gho.Product.Key}_{gho.BizId}" ,  amountDebit :  GetAmount(gho)  ); //j
        //         (gho as OrderItem).RecordedInAcc = true;
        //     }
        //     foreach (var yso in ysos)
        //     {
        //         av.AddAccItem(yso, Account.KCSP, $"收货_{yso.Product.Key}_{yso.BizId}" , amountCredit  :  GetAmount(yso)  ); //d
        //         (yso as OrderItem).RecordedInAcc = true;
        //     }
        //     
        //     // av.State = VoucherState.自平;
        //     
        //     return av;
        // }


        public IDayBasedWorkFlowNodeAccountingVoucherSetWrapper CreateAVs()
        {
            IDayBasedWorkFlowNodeAccountingVoucherSetWrapper vs =
                new DayBasedWorkFlowNodeAccountingVoucherSetWrapper(this);


            _voucherSets[vs.AccPeriod.ToString()] = vs;
            return vs;
        }


        Dictionary<string, IDayBasedWorkFlowNodeAccountingVoucherSetWrapper> _voucherSets =
            new Dictionary<string, IDayBasedWorkFlowNodeAccountingVoucherSetWrapper>();

        public IOrderItemBasedAccountingVoucher GetMyVoucherByOrderId(string bizid, bool onlyLeft = true)
        {
            var bothside = !onlyLeft;

            var av = _voucherSets.Values.SelectMany(x => x.Vouchers)
                .FirstOrDefault(x => (x.AccItems
                                          .Count(y => y.RelatedOrderItem.BizId == bizid && (bothside
                                              || y.AmountCredit.Equals(new Amount(0, 0)))) >
                                      0));

            return av;
        }


        IWorkFlowManager _workFlowManager;

        public IWorkFlowNodeWrapper GetHistoryUnRecorderOrder(AccountPeriod period)
        {
            return _workFlowManager.GetUnRecordedInAccYanShouNode(period);
        }

        IRepoPaiShi _repoPaiShi;

        public IDayBasedWorkFlowNodeAccountingVoucherSetWrapper GetDayBasedVoucherSet(AccountPeriod perio)
        {
            if (_voucherSets.ContainsKey(perio.ToString()))
                return _voucherSets[perio.ToString()];

            //load avs from db
            IDayBasedWorkFlowNodeAccountingVoucherSetWrapper res = _repoPaiShi.GetAVS(perio);

            return res;
        }

        public IWorkFlowNodeWrapper GetLeftNode(AccountPeriod period)
        {
            return _workFlowManager.GetByBatchNo(period, BizFlowNodeEnum.FaHuo);
        }

        public IWorkFlowNodeWrapper GetRightNode(AccountPeriod period, bool IncludeFromProductionLine = true,
            bool IncludeFromRegroup = false)
        {
            return _workFlowManager.GetByYanShouNode(period, fromProdLine: IncludeFromProductionLine,
                fromRegroup: IncludeFromRegroup);
        }

        public IWorkFlowNodeWrapper GetNode(AccountPeriod period, AccountPeriod jyPeriod, BizFlowNodeEnum node)
        {
            if (node == BizFlowNodeEnum.Zuhuo)
                return _workFlowManager.GetZuhuoNode(period, jyPeriod);
            else if (node == BizFlowNodeEnum.FaHuo)
                return _workFlowManager.GetByFahuoNodde(period, jyPeriod);

            else
            {
                return _workFlowManager.GetByBatchNo(period, node);
            }
        }


        private IPriceManagerPort _priceManagerPort;
        private IConfigT _config;

        public AccountingVoucherManager(IPriceManagerPort priceManagerPort, IConfigT config,
            IWorkFlowManager workFlowManager, IRepoPaiShi repoPaiShi)
        {
            _priceManagerPort = priceManagerPort;
            _config = config;
            _workFlowManager = workFlowManager;
            _repoPaiShi = repoPaiShi;
        }

        Amount GetAmount(IOrderItem orderItem)
        {
            // var price= _priceManagerPort.GetPrice(
            //     orderItem.BizTime,  
            //      orderItem.Product , 
            //     _config.ConfigSys.SmartChoosePrice );

            return new Amount(amount: orderItem.Amount, quantity: orderItem.Quantity);
        }
    }
}